package com.lagou.service;

import com.lagou.mapper.EmployeeMapper;
import com.lagou.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
/** 注解@CacheConfig：标注在类上，抽取缓存相关注解的公共配置，可抽取的公共配置有缓存名字、主键生成器等 */
@CacheConfig(cacheNames = {"emp"})
public class EmployeeService {

	@Autowired
	private EmployeeMapper employeeMapper;

	/**
	 * 注解@Cacheable：缓存查询，会将该方法的返回值存到缓存中
	 *     属性：value/cacheNames：指定缓存的名称，cacheManager是管理多个cache，以名称进行区分
	 *          key：缓存数据时指定key值（cache以key,value方式存储），key默认是方法的参数值，也可以使用spEL来计算key值
	 *          keyGenerator：key的生成策略，和key属性二选一。可以自定义keyGenerator
	 *          cacheManager：指定缓存管理器。有redis、ehcache
	 *          cacheResolver：功能跟cacheManager相同，二选一即可
	 *          condition：条件属性，满足这个条件才会进行缓存
	 *          unless：否定条件，满足这个条件不进行缓存
	 *          sync：是否使用异步模式进行缓存，true为异步
	 *     (1) condition/unless 同时满足，不缓存
	 *     (2) sync的值为true时，unless不被支持
	 */
	@Cacheable(/*cacheNames = {"emp"},*/ key = "#id", condition = "#id>0", unless = "#result == null")
	public Employee getEmpById(Integer id) {
		Employee emp = employeeMapper.getEmpById(id);
		return emp;
	}


	/** 注解@CachePut
	 * 1、说明：既调用方法，又更新缓存数据，一般用于更新操作，在更新缓存时一定要和想更新的缓存有相同的缓存名称和相同的key(可类比同一张表的同一条数据)
	 * 2、运行时机：①先调用目标方法    ②将目标方法的结果缓存起来
	 * 3、@CachePut标注的方法总会被调用，且调用之后才将结果放入缓存，因此可以使用#result获取到方法的返回值。
	 */
	@CachePut(/*cacheNames = {"emp"},*/ key = "#employee.id")
	public Employee updateEmp(Employee employee){
		employeeMapper.updateEmp(employee);
		return employee;
	}


	/** 注解@CacheEvict
	 * 说明：缓存清除，清除缓存时要指明缓的名字和key，类似告诉数据库要删除哪个表中的哪条数据。key默认为参数的值
	 * 属性：beforeInvocation：设置为true时则会在方法调用之前清除缓存
	 */
	@CacheEvict(/*cacheNames = {"emp"},*/ key = "#id", beforeInvocation = true)
	public void delEmp(Integer id) {
		employeeMapper.deleteEmpById(id);
	}

}
